/* Copyright 2012 Tobias Marschall
 * 
 * This file is part of CLEVER.
 * 
 * CLEVER is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * CLEVER is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with CLEVER.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>

#include "ReadAssignmentFileReader.h"

using namespace std;

ReadAssignmentFileReader::ReadAssignmentFileReader(const std::string& filename) : ifs(filename.c_str()), current_entry(0) {
	if (ifs.fail()) {
		throw std::runtime_error("Error opening file \""+filename+"\"");
	}
	if (ifs) {
		string line;
		getline(ifs, line);
		parseEntry(line);
	}
}

ReadAssignmentFileReader::~ReadAssignmentFileReader() {
}

void ReadAssignmentFileReader::parseEntry(const std::string& line) {
	current_entry = auto_ptr<entry_t>(new entry_t());
	typedef boost::tokenizer<boost::char_separator<char> > tokenizer_t;
	boost::char_separator<char> whitespace_separator(" \t");
	boost::char_separator<char> comma_separator(",");
	tokenizer_t tokenizer(line,whitespace_separator);
	vector<string> tokens(tokenizer.begin(), tokenizer.end());
	if (tokens.size() < 1) {
		throw std::runtime_error("Error parsing read assignments. 1");
	}
	try {
		current_entry->read_name = tokens[0];
		for (size_t i=1; i<tokens.size(); ++i) {
			tokenizer_t sub_tokenizer(tokens[i],comma_separator);
			tokenizer_t::const_iterator it = sub_tokenizer.begin();
			vector<string> sub_tokens(sub_tokenizer.begin(), sub_tokenizer.end());
			if (sub_tokens.size() != 2) {
				throw std::runtime_error("Error parsing read assignments. 2");
			}
			int variation_id = boost::lexical_cast<int>(sub_tokens[0]);
			int pair_nr = boost::lexical_cast<int>(sub_tokens[1]);
			current_entry->assignments.push_back(make_pair(variation_id, pair_nr));
		}
	} catch(boost::bad_lexical_cast &){
		throw std::runtime_error("Error parsing read assignments. 3");
	}

}

void ReadAssignmentFileReader::advance() {
	string line;
	if (getline(ifs, line)) {
		parseEntry(line);
	} else {
		current_entry = auto_ptr<entry_t>(0);
	}
}

bool ReadAssignmentFileReader::finished() const {
	return current_entry.get() == 0;
}


const std::string & ReadAssignmentFileReader::getReadName() const {
	assert(current_entry.get() != 0);
	return current_entry->read_name;
}



const std::vector<std::pair<int,int> >& ReadAssignmentFileReader::getAssignments() const {
	assert(current_entry.get() != 0);
	return current_entry->assignments;
}
